package com.dongnan.hl7v2;

import java.io.ObjectStreamException;
import java.io.Serializable;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.LinkedList;
import java.util.Properties;
import utils.PropertiesUtils;
public class DataBaseCconnectPool implements Serializable  {

    private static final long serialVersionUID = -4827759752671402638L;
    private volatile static DataBaseCconnectPool dataBaseCconnectPool = null;

    private LinkedList<Connection> linkedlist1=new LinkedList<Connection>();
    private String driver;//
    private  String url;//
    private  String username;//数据库登陆名
    private  String password;//数据库的登陆密码
    private  int jdbcConnectionInitSize = 20;//最小连接数量
    private  int max=1; //当前最大连接数量=max*jdbcConnectionInitSize
    private DataBaseCconnectPool(){
        try {
            Properties prop= PropertiesUtils.loadProperties("/application.properties");
            driver=prop.getProperty("driverClassName");
            url=prop.getProperty("dbUrl");
            username=prop.getProperty("userName");
            password=prop.getProperty("passWord");
            Class.forName(driver);

            //创建最小连接数个数据库连接对象以备使用
            for(int i=0;i<jdbcConnectionInitSize;i++){
                Connection conn= DriverManager.getConnection(url, username, password);
                linkedlist1.add(conn);
            }


        } catch (SQLException e) {
// TODO Auto-generated catch block
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    public static DataBaseCconnectPool getInstance(){
        if(dataBaseCconnectPool == null){
            //注意是synchronized 字节码，不是synchronized 对象
            synchronized(DataBaseCconnectPool.class){
                if(dataBaseCconnectPool == null){
                    dataBaseCconnectPool = new DataBaseCconnectPool();
                }
            }
        }
        return dataBaseCconnectPool;
    }

    @Override
    public String toString() {
        return "数据库连接池";
    }

    private Object readResolve() throws ObjectStreamException {
        return getInstance();
    }

    /*
    * 实现数据库连接的获取和新创建
    */
    public Connection getConnection() throws SQLException {
//如果集合中没有数据库连接对象了，且创建的数据库连接对象没有达到最大连接数量，可以再创建一组数据库连接对象以备使用
        if(linkedlist1.size()==0&&max<=5){
            try {
                Class.forName("com.mysql.jdbc.Driver");
            } catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
                e.printStackTrace();
            }
            for(int i=0;i<jdbcConnectionInitSize;i++){
                Connection conn=DriverManager.getConnection(url, username, password);
//                System.out.println("获取到了链接" + conn);
//将创建好的数据库连接对象添加到Linkedlist集合中
                linkedlist1.add(conn);
            }
            max++;
        }
        if(linkedlist1.size()>0){
//从linkedlist集合中取出一个数据库链接对象Connection使用
            final Connection conn1=linkedlist1.removeFirst();
            System.out.println("linkedlist1数据库连接池大小是" + linkedlist1.size());
/*返回一个Connection对象，并且设置Connection对象方法调用的限制，
*当调用connection类对象的close()方法时会将Connection对象重新收集放入linkedlist集合中。
*/
            return (Connection) Proxy.newProxyInstance(conn1.getClass().getClassLoader(),//这里换成JdbcConnectionsPool.class.getClassLoader();也行
                    conn1.getClass().getInterfaces(), new InvocationHandler() {

                        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                            if(!method.getName().equalsIgnoreCase("close")){
                                return method.invoke(conn1, args);
                            }else{
                                linkedlist1.add(conn1);
//                                System.out.println(conn1+"对象被释放，重新放回linkedlist集合中！");
//                                System.out.println("此时Linkedlist集合中有"+linkedlist1.size()+"个数据库连接对象！");
                                return null;
                            }
                        }
                    });
        }else{
            System.out.println("连接数据库失败！");
        }
        return null;
    }
}
